package com.bitcola.security.activity.biz;


import com.alibaba.fastjson.JSON;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.bitcola.security.activity.constant.PrizeConstant;
import com.bitcola.entity.ApplyLog;
import com.bitcola.entity.ApplyProject;
import com.bitcola.security.activity.entity.UserMining;
import com.bitcola.security.activity.feign.IDataServiceFeign;
import com.bitcola.security.activity.mapper.BalanceChangeLogMapper;
import com.bitcola.security.activity.mapper.ColaUserBalanceMapper;
import com.bitcola.security.activity.mapper.LabsApplyLogMapper;
import com.bitcola.security.activity.mapper.LabsApplyMapper;
import com.bitcola.security.auth.common.util.EncoderUtil;
import com.bitcola.security.common.constant.BalanceTypeConstants;
import com.bitcola.security.common.constant.FinancialConstant;
import com.bitcola.security.common.exception.LackBalanceException;
import com.bitcola.security.common.exception.NoAmountException;
import com.bitcola.security.common.exception.ParamLimitException;
import com.bitcola.security.common.exception.RepeatException;
import com.bitcola.security.common.util.Snowflake;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApplyBiz {
    @Autowired
    BalanceChangeLogMapper balanceChangeLogMapper;
    Snowflake snowflake = new Snowflake(5, 11);

    @Resource
    IDataServiceFeign dataServiceFeign;

    @Autowired
    LabsApplyLogMapper applyLogMapper;
    @Autowired
    LabsApplyMapper labsApplyMapper;
    @Autowired
    ColaUserBalanceMapper colaUserBalanceMapper;

    @Autowired
    BalanceChangeBiz balanceChangeBiz;
    @Autowired
            MiningBiz miningBiz;

    @Autowired
            UserInviterBiz userInviterBiz;


    long dayTime = 24 * 60 * 60 * 1000;
    @Autowired
    LockBiz lockBiz;

    @Cached(expire = 2,cacheType = CacheType.LOCAL)
    public List<ApplyProject> queryProject(String status) {
        Example example = new Example(ApplyProject.class);
        if (!StringUtils.isEmpty(status)) example.createCriteria().andEqualTo("status", status);
         example.orderBy("startTime").desc();
        return labsApplyMapper.selectByExample(example);
    }


    @Transactional
    public ApplyLog apply(String userId, BigDecimal number, BigDecimal dudect, String labsProjectId) {
        ApplyProject applyProject = getById(labsProjectId);


        String symbol = applyProject.getSymbol();
        String coinCode = applyProject.getCoinCode();
        BigDecimal price = applyProject.getPrice();
        BigDecimal maxDudectt = applyProject.getMaxDudect();
        if (dudect.compareTo(number.multiply(maxDudectt)) > 0) throw new ParamLimitException("");
        BigDecimal totalAmount = number;
        number = number.subtract(dudect);
        BigDecimal totalPrice = number.negate().multiply(price);
        int index = colaUserBalanceMapper.changeUserBanlance(userId, symbol, totalPrice, BigDecimal.ZERO, dudect.negate().multiply(price), dudect.multiply(price), BigDecimal.ZERO, BigDecimal.ZERO, EncoderUtil.BALANCE_KEY);
        if (index == 0) throw new LackBalanceException("");
        ApplyLog applyLog = new ApplyLog();
//        var net=userInviterBiz.userNetMap.get(userId);
//
//
//        totalPrice=totalPrice.negate();

//         var list= net.getUserMinings().stream().filter(UserMining::isActive).collect(Collectors.toList());
//         if(totalPrice.compareTo(BigDecimal.valueOf(50))>0&&totalPrice.compareTo(BigDecimal.valueOf(100))<=0){//必须要有黄金
//             if(list.stream().noneMatch(x -> x.getLevel() == 4)) throw  new RepeatException("");
//
//         }else if(totalPrice.compareTo(BigDecimal.valueOf(20))>0&&totalPrice.compareTo(BigDecimal.valueOf(50))<=0)//翡翠{}
//         {
//             if(list.stream().noneMatch(x -> x.getLevel() == 3)) throw  new RepeatException("");
//         }else if(totalPrice.compareTo(BigDecimal.valueOf(100))>0){
//             throw  new ParamLimitException("");
//         }else  if(totalPrice.compareTo(BigDecimal.valueOf(10))>0&&totalPrice.compareTo(BigDecimal.valueOf(20))<=0)//白银
//         {
//             if(list.stream().noneMatch(x -> x.getLevel() == 2)) throw  new RepeatException("");
//
//
//         }
         Example example=new Example(ApplyLog.class);

         example.createCriteria().andEqualTo("userId",userId).andEqualTo("projectId",labsProjectId);
           long count =applyLogMapper.selectCountByExample(example);
         if(count>0) throw  new RepeatException("");


        applyLog.setType("point");
        if ("point".equals(applyProject.getType())) {
            int num=number.intValue();
            for (int i = 0; i <num ; i++) {
                miningBiz.applyNewMiningPoint(userId,"2",true, new Date());

            }



        } else if (!"point".equals(applyProject.getType()) && (applyProject.getRush() == null || applyProject.getRush() == 0)) {
//            colaUserBalanceMapper.changeUserBanlance(userId, coinCode, number, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, EncoderUtil.BALANCE_KEY);
        } else {
            if (applyProject.getRealAmount() == null) applyProject.setRealAmount(applyProject.getRemindNumber());
            if (applyProject.getRealAmount().compareTo(BigDecimal.ZERO) == 0) {


                applyProject.setRemindNumber(BigDecimal.ZERO);
                applyProject.setStatus("END");
                applyProject.setEndTime(new Date());
                applyProject.setRemindNumber(BigDecimal.ZERO);
                labsApplyMapper.updateByPrimaryKey(applyProject);

                throw new NoAmountException("");
            }


            totalAmount = totalAmount.multiply(applyProject.getTotalNumber().divide(applyProject.getRealAmount(), 4, RoundingMode.DOWN));

            colaUserBalanceMapper.changeUserBanlance(userId, coinCode, number, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, EncoderUtil.BALANCE_KEY);

        }
        index = labsApplyMapper.apply(labsProjectId, totalAmount);
        if (index == 0) {//没有额度了  设置成结束
            applyProject.setStatus("END");
            applyProject.setEndTime(new Date());
            applyProject.setRemindNumber(BigDecimal.ZERO);
            labsApplyMapper.updateByPrimaryKey(applyProject);
            throw new NoAmountException("");
        }
        applyLog.setId(snowflake.nextIdStr());
        applyLog.setUserId(userId);
        applyLog.setPrice(applyProject.getPrice());
        applyLog.setCoinCode(coinCode);
        applyLog.setSymbol(symbol);
        applyLog.setCreateTime(new Date());
        applyLog.setProjectId(labsProjectId);
        applyLog.setNumber(number);
        applyLog.setDudect(dudect);
        applyLog.setRound(applyProject.getRound());
        applyLog.setRush(applyProject.getRush());

        applyLogMapper.insert(applyLog);
        if (dudect.compareTo(BigDecimal.ZERO) > 0) {
//            lockBiz.createLockPosition(labsProjectId, userId, dudect, dayTime, BigDecimal.valueOf(0.01), coinCode, applyProject.getCoinCodeIcon());
//            balanceChangeBiz.createChange(userId, BalanceTypeConstants.prize_balance_frozen, null, dudect.negate().multiply(price), FinancialConstant.APPLY, symbol);
////            balanceChangeBiz.createChange(userId, BalanceTypeConstants.prize_balance_released, null,  dudect.multiply(price), FinancialConstant.APPLY, symbol);


        }
//        balanceChangeBiz.createChange(userId, BalanceTypeConstants.APPLY_AMOUNT, null, number, FinancialConstant.APPLY, coinCode);
//        balanceChangeBiz.createChange(userId, BalanceTypeConstants.BALANCE, null, totalPrice, FinancialConstant.APPLY, symbol);



        return applyLog;


    }


    @Cached(cacheType = CacheType.LOCAL, expire = 2)
    public ApplyProject getById(String id) {
        return labsApplyMapper.selectByPrimaryKey(id);
    }




    @Transactional
    public void prizeInvitor(String userId, BigDecimal amount, String coinCode, int level) {
        BigDecimal actor = BigDecimal.valueOf(0.04);


        amount = amount.multiply(actor);
        int index = colaUserBalanceMapper.changeUserBanlance(userId, coinCode, amount, BigDecimal.ZERO, BigDecimal.ZERO, amount, BigDecimal.ZERO, BigDecimal.ZERO, EncoderUtil.BALANCE_KEY);

        if (amount.compareTo(BigDecimal.ZERO) > 0) {
            balanceChangeBiz.createChange(userId, BalanceTypeConstants.BALANCE, PrizeConstant.APPLY_PRIZE, amount, FinancialConstant.ACTIVITY_REWARD, coinCode);

        }

    }

    @Transactional

    public void addMarketUserAccount(String userId, String coinCode, BigDecimal amount) {
        balanceChangeBiz.createChange(userId, BalanceTypeConstants.BALANCE, PrizeConstant.APPLY_PRIZE, amount, FinancialConstant.APPLY, coinCode);
        colaUserBalanceMapper.changeUserBanlance(userId, coinCode, amount, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, EncoderUtil.BALANCE_KEY);


    }


}
